package com.xonro.common.histrans.base.biz;

import com.actionsoft.bpms.bpmn.engine.model.run.HistoryTaskInstanceModel;
import com.actionsoft.bpms.bpmn.engine.model.run.ProcessInstanceModel;
import com.actionsoft.bpms.bpmn.engine.model.run.TaskInstanceModel;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.ProcessInstance;
import com.actionsoft.bpms.bpmn.engine.model.run.delegate.TaskInstance;
import com.actionsoft.bpms.commons.database.RowMap;
import com.actionsoft.bpms.org.model.UserModel;
import com.actionsoft.bpms.util.DBSql;
import com.actionsoft.bpms.util.UUIDGener;
import com.actionsoft.sdk.local.SDK;
import com.actionsoft.sdk.service.model.TaskComment;
import com.xonro.common.histrans.base.consts.DrpConst;
import com.xonro.common.histrans.base.ctx.BOCreateData;
import com.xonro.common.histrans.base.ctx.FileTransData;
import com.xonro.common.histrans.base.ctx.HistoryTransContext;
import com.xonro.common.histrans.base.model.HistoryTransLogModel;
import com.xonro.common.histrans.util.FileUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.sql.Connection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @Author:zhuw
 * @Description:
 * @Date 2022/3/23
 */
public class ProcessPersistBiz {
    private static final String processInsertSql = "INSERT INTO WFC_PROCESS(SECURITYLAYER,CREATEUSERROLEID,ENDTIME,REMINDTIMES,STARTACTIVITYID,CREATEUSERDEPTID,IOBD,CREATEUSER,ENDACTIVITYID,ISOVERTIME,CREATEUSERORGID,ISSTART,ID,PROCESSTITLE,EXPIRETIME,CREATETIME,ISEXISTSUBPROC,COSTTTIME,ISTRASH,BUSINESSKEY,CONTROLSTATE,ISEXCEPTION,PROCESSDEFVERID,PROCESSGROUPID,STARTTIME,ISASYNC,EXT7,EXT8,ISPROCESS,STARTTASKINSTID,ISEND,PROCESSINSTTYPE,PROCESSDEFID,CREATEUSERLOCATION) VALUES (:SECURITYLAYER,:CREATEUSERROLEID,:ENDTIME,:REMINDTIMES,:STARTACTIVITYID,:CREATEUSERDEPTID,:IOBD,:CREATEUSER,:ENDACTIVITYID,:ISOVERTIME,:CREATEUSERORGID,:ISSTART,:ID,:PROCESSTITLE,:EXPIRETIME,:CREATETIME,:ISEXISTSUBPROC,:COSTTTIME,:ISTRASH,:BUSINESSKEY,:CONTROLSTATE,:ISEXCEPTION,:PROCESSDEFVERID,:PROCESSGROUPID,:STARTTIME,:ISASYNC,:EXT7,:EXT8,:ISPROCESS,:STARTTASKINSTID,:ISEND,:PROCESSINSTTYPE,:PROCESSDEFID,:CREATEUSERLOCATION)";
    private final String wfcSql = "INSERT INTO WFC_TASK(TARGET,DELAYTIMES,REMINDTIMES,ACTIVITYTYPE,PRIORITY,IOBD,READSTATE,TASKTITLE,ISMONITOR,SECURITYLEVEL,OWNER,PARENTTASKINSTID,ID,BEGINENGINENODE,READTIME,TARGETROLEID,ISTRASH,BEGINTIME,TARGETDEPTID,CONTROLSTATE,ACTIVITYDEFID,TARGETCOMPANYID,PROCESSINSTID,DISPATCHID,PROCESSDEFVERID,PROCESSGROUPID,TASKSTATE,ISASYNC,SCOPEID,CLAIMTYPE,OWNERDEPTID,PROCESSDEFID) VALUES (:TARGET,:DELAYTIMES,:REMINDTIMES,:ACTIVITYTYPE,:PRIORITY,:IOBD,:READSTATE,:TASKTITLE,:ISMONITOR,:SECURITYLEVEL,:OWNER,:PARENTTASKINSTID,:ID,:BEGINENGINENODE,:READTIME,:TARGETROLEID,:ISTRASH,:BEGINTIME,:TARGETDEPTID,:CONTROLSTATE,:ACTIVITYDEFID,:TARGETCOMPANYID,:PROCESSINSTID,:DISPATCHID,:PROCESSDEFVERID,:PROCESSGROUPID,:TASKSTATE,:ISASYNC,:SCOPEID,:CLAIMTYPE,:OWNERDEPTID,:PROCESSDEFID)";
    private final String wfhSql = "INSERT INTO WFH_TASK(TARGET,DELAYTIMES,ISUNDO,REMINDTIMES,ACTIVITYTYPE,PRIORITY,IOBD,READSTATE,TASKTITLE,ISMONITOR,SECURITYLEVEL,OWNER,PARENTTASKINSTID,ID,BEGINENGINENODE,READTIME,COSTTTIME,TARGETROLEID,ISTRASH,BEGINTIME,TARGETDEPTID,CONTROLSTATE,ACTIVITYDEFID,TARGETCOMPANYID,PROCESSINSTID,DISPATCHID,PROCESSDEFVERID,PROCESSGROUPID,TASKSTATE,ISASYNC,SCOPEID,CLAIMTYPE,OWNERDEPTID,PROCESSDEFID, ENDTIME) VALUES (:TARGET,:DELAYTIMES,:ISUNDO,:REMINDTIMES,:ACTIVITYTYPE,:PRIORITY,:IOBD,:READSTATE,:TASKTITLE,:ISMONITOR,:SECURITYLEVEL,:OWNER,:PARENTTASKINSTID,:ID,:BEGINENGINENODE,:READTIME,:COSTTTIME,:TARGETROLEID,:ISTRASH,:BEGINTIME,:TARGETDEPTID,:CONTROLSTATE,:ACTIVITYDEFID,:TARGETCOMPANYID,:PROCESSINSTID,:DISPATCHID,:PROCESSDEFVERID,:PROCESSGROUPID,:TASKSTATE,:ISASYNC,:SCOPEID,:CLAIMTYPE,:OWNERDEPTID,:PROCESSDEFID, :ENDTIME)";


    private static ProcessPersistBiz processPersistBiz = new ProcessPersistBiz();

    public static ProcessPersistBiz getInstance() {
        return processPersistBiz;
    }

    public void persistBO(Connection connection, HistoryTransContext historyTransContext) {
        List<BOCreateData> boCreateDatas = historyTransContext.getProcessCreateContext().getBoCreateDatas();
        if (CollectionUtils.isNotEmpty(boCreateDatas)) {
            for (BOCreateData boCreateData : boCreateDatas) {
                SDK.getBOAPI().create(boCreateData.getBoName(), boCreateData.getBo(),
                        historyTransContext.getProcessCreateContext().getProcessInstanceModel().getId(),
                        getUserExchange(boCreateData.getCreateUser())  ,
                        connection);
            }

        }

    }

    private  String getUserExchange(String oaUserId){
        if("jiwenhan2020".equals(oaUserId)){
            return "jiwenhao_ky";
        }
        String sql="SELECT * FROM ORGUSER WHERE USERID='"+oaUserId+"_ky'";
        RowMap map = DBSql.getMap(sql);
        if(Objects.isNull(map)){
            return oaUserId;
        }
        return oaUserId+"_ky";
    }


    public void persistComment(Connection connection, HistoryTransContext historyTransContext) {
        List<TaskComment> taskCommentModels = historyTransContext.getProcessCreateContext().getTaskCommentModels();
        if (CollectionUtils.isNotEmpty(taskCommentModels)) {
            for (TaskComment taskComment : taskCommentModels) {
                insertWfcComment(connection, taskComment);
            }
        }
        List<TaskComment> taskHistoryCommentModels = historyTransContext.getProcessCreateContext().getTaskHistoryCommentModels();
        if (CollectionUtils.isNotEmpty(taskHistoryCommentModels)) {
            for (TaskComment taskComment : taskHistoryCommentModels) {
                insertWfhComment(connection, taskComment);
            }
        }
    }

    private void insertWfhComment(Connection connection, TaskComment taskComment) {
        Map<String, Object> params = new HashMap<>();
        params.put("ID", taskComment.getId());
        params.put("PROCESSINSTID", taskComment.getProcessInstId());
        params.put("TASKINSTID", taskComment.getTaskInstId());
        params.put("CREATEDATE", taskComment.getCreateDate());
        params.put("CREATEUSER", taskComment.getCreateUser());
        params.put("ACTIONNAME", taskComment.getActionName());
        params.put("ACTIVITYNAME", taskComment.getActivityName());
        params.put("MSG", taskComment.getMsg());
        UserModel user = SDK.getORGAPI().getUser(taskComment.getCreateUser());
        if (user != null) {
            params.put("CREATEUSERNAME", user.getUserName());

        }
        DBSql.update(connection,
                "INSERT INTO WFH_COMMENT (ID ,PROCESSINSTID ,TASKINSTID ,CREATEDATE ,CREATEUSER ,ACTIONNAME ,ACTIVITYNAME ,MSG) " +
                        " VALUES " +
                        " (:ID ,:PROCESSINSTID ,:TASKINSTID, :CREATEDATE, :CREATEUSER, :ACTIONNAME,  :ACTIVITYNAME, :MSG)"
                , params

        );
    }

    private void insertWfcComment(Connection connection, TaskComment taskComment) {
    }

    public void persistProcess(Connection connection, HistoryTransContext historyTransContext) {
        ProcessInstanceModel processInstanceModel = historyTransContext.getProcessCreateContext().getProcessInstanceModel();
        insertProcess(connection, processInstanceModel);
    }

    public void persistTask(Connection connection, HistoryTransContext historyTransContext) {
        List<HistoryTaskInstanceModel> historyTaskInstanceModels = historyTransContext.getProcessCreateContext().getHistoryTaskInstanceModels();
        if(CollectionUtils.isNotEmpty(historyTaskInstanceModels)){
            for(HistoryTaskInstanceModel historyTaskInstanceModel: historyTaskInstanceModels)
            insertTask(connection, historyTaskInstanceModel);
        }
        List<TaskInstanceModel> taskInstanceModels = historyTransContext.getProcessCreateContext().getTaskInstanceModels();
        if(CollectionUtils.isNotEmpty(taskInstanceModels)){
            for(TaskInstanceModel taskInstanceModel: taskInstanceModels)
            insertTask(connection, taskInstanceModel);
        }
    }

    private int insertProcess(Connection connection, ProcessInstance processInstance) {
        Map<String, Object> params = new HashMap<>();
        params.put("ID", processInstance.getId());
        params.put("BUSINESSKEY", processInstance.getProcessBusinessKey());
        params.put("PROCESSDEFID", processInstance.getProcessDefId());
        params.put("PROCESSDEFVERID", processInstance.getProcessDefVerId());
        params.put("CONTROLSTATE", processInstance.getControlState());
        params.put("PROCESSGROUPID", processInstance.getProcessGroupId());
        params.put("PROCESSTITLE", processInstance.getTitle());
        params.put("STARTACTIVITYID", processInstance.getStartActivityId());
        params.put("STARTTASKINSTID", processInstance.getStartTaskInstId());
        params.put("STARTTIME", processInstance.getStartTime());
        params.put("PROCESSINSTTYPE", 0);
        params.put("SECURITYLAYER", 0);
        params.put("CREATEUSER", processInstance.getCreateUser());
        params.put("CREATETIME", processInstance.getCreateTime());
        params.put("CREATEUSERORGID", "8911e732-b42a-4556-853f-ad32761bcbee");
        params.put("CREATEUSERDEPTID", processInstance.getCreateUserDeptId());
        params.put("CREATEUSERROLEID", processInstance.getCreateUserRoleId());
        params.put("CREATEUSERLOCATION", processInstance.getCreateUserLocation());
        params.put("ENDACTIVITYID", processInstance.getEndActivityId());
        params.put("ENDTIME", processInstance.getEndTime());
        params.put("ISPROCESS", 1);
        params.put("ISSTART", 1);
        params.put("ISEND", processInstance.isEnd() ? 1 : 0);
        params.put("ISASYNC", 0);
        params.put("ISEXCEPTION", 0);
        params.put("ISOVERTIME", 0);
        params.put("ISEXISTSUBPROC", 0);
        params.put("COSTTTIME", 0);
        params.put("EXPIRETIME", 0);
        params.put("IOBD", processInstance.getIOBD());
        params.put("REMINDTIMES", 0);
        params.put("EXT7", 0);
        params.put("EXT8", 0);
        params.put("ISTRASH", 0);

        return DBSql.update(connection, processInsertSql, params);
    }

    private void insertWfc(Connection connection, Map<String, Object> params, TaskInstance taskInstance) {
        DBSql.update(connection, wfcSql, params);
    }

    private void insertWfh(Connection connection, Map<String, Object> params, TaskInstance taskInstance) {
        params.put("COSTTTIME", 0);
        params.put("ISUNDO", 0);
        params.put("ENDTIME", taskInstance.getEndTime());
        DBSql.update(connection, wfhSql, params);
    }

    public void insertTask(Connection connection, TaskInstance taskInstance) {
        Map<String, Object> params = new HashMap<>();
        params.put("ID", taskInstance.getId());
        params.put("PARENTTASKINSTID", taskInstance.getParentTaskInstId());
        params.put("SCOPEID", taskInstance.getParentTaskInstId());
        params.put("ACTIVITYTYPE", "userTask");
        params.put("ACTIVITYDEFID", taskInstance.getActivityDefId());
        params.put("PROCESSINSTID", taskInstance.getProcessInstId());
        params.put("PROCESSDEFID", taskInstance.getProcessDefId());
        params.put("PROCESSDEFVERID", taskInstance.getProcessDefVerId());
        params.put("PROCESSGROUPID", taskInstance.getProcessGroupId());
        params.put("DISPATCHID", UUIDGener.getUUID());
        params.put("TASKTITLE", taskInstance.getTitle());
        params.put("TASKSTATE", 1);
        params.put("CONTROLSTATE", taskInstance.getControlState());
        params.put("PRIORITY", 1);
        params.put("OWNER", taskInstance.getOwner());
        params.put("TARGET", taskInstance.getTarget());
        params.put("CLAIMTYPE", 0);
        params.put("BEGINTIME", taskInstance.getBeginTime());
        params.put("BEGINENGINENODE", "localhost:10008");
        params.put("READTIME", taskInstance.getEndTime());
        params.put("OWNERDEPTID", taskInstance.getOwnerDepartmentId());
        params.put("TARGETDEPTID", taskInstance.getTargetDepartmentId());
        params.put("TARGETCOMPANYID", "8911e732-b42a-4556-853f-ad32761bcbee");
        params.put("TARGETROLEID", taskInstance.getTargetRoleId());
        params.put("ISMONITOR", 0);
        params.put("ISASYNC", 0);
        params.put("IOBD", taskInstance.getIOBD());
        params.put("REMINDTIMES", 0);
        params.put("DELAYTIMES", 0);
        params.put("SECURITYLEVEL", 0);
        params.put("ISTRASH", 0);
        params.put("READSTATE", 0);
        if (taskInstance.getEndTime() == null) {
            insertWfc(connection, params, taskInstance);
        } else {
            insertWfh(connection, params, taskInstance);
        }

    }

    public void insertHistoryTransLog(Connection connection, HistoryTransLogModel historytransLogModel) {
        RowMap map = DBSql.getMap(connection, "SELECT ID FROM BO_EU_HISTRANS_LOG WHERE OUTER_TABLE = ? AND OUTER_PK  = ?",
                historytransLogModel.getOuterTable(), historytransLogModel.getOuterPK());
        Map<String, Object> params = new HashMap<>();
        params.put("ISEND", 1);
        params.put("BINDID", historytransLogModel.getBindId());
        params.put("BPM_BOID", historytransLogModel.getBpmBOId());
        params.put("BPM_EXT1", historytransLogModel.getBpmExt1());
        params.put("BPM_EXT2", historytransLogModel.getBpmExt2());
        params.put("BPM_TABLE", historytransLogModel.getBpmTable());
        params.put("OUTER_TABLE", historytransLogModel.getOuterTable());
        params.put("OUTER_PK", historytransLogModel.getOuterPK());
        params.put("OUTER_EXT1", historytransLogModel.getOuterExt1());
        params.put("OUTER_EXT2", historytransLogModel.getOuterExt2());
        params.put("OUTER_EXT3", historytransLogModel.getOuterExt3());
        params.put("OUTER_CONTENT1", historytransLogModel.getOuterContent1());
        params.put("OUTER_CONTENT2", historytransLogModel.getOuterContent2());
        params.put("OUTER_CONTENT3", historytransLogModel.getOuterContent3());
        params.put("OUTER_CONTENT4", historytransLogModel.getOuterContent4());
        params.put("OUTER_CONTENT5", historytransLogModel.getOuterContent5());
        params.put("OUTER_CONTENT6", historytransLogModel.getOuterContent6());
        params.put("OUTER_CONTENT7", historytransLogModel.getOuterContent7());
        params.put("OUTER_CONTENT8", historytransLogModel.getOuterContent8());
        params.put("OUTER_CONTENT9", historytransLogModel.getOuterContent9());
        params.put("OUTER_CONTENT10", historytransLogModel.getOuterContent10());
        if (map == null) {
            params.put("ID", UUIDGener.getUUID());
            DBSql.update(
                    "INSERT INTO BO_EU_HISTRANS_LOG (ID, ISEND" +
                            ",BINDID" +
                            ",BPM_BOID" +
                            ",BPM_EXT1" +
                            ",BPM_EXT2" +
                            ",BPM_TABLE" +
                            ",OUTER_TABLE" +
                            ",OUTER_PK" +
                            ",OUTER_EXT1" +
                            ",OUTER_EXT2" +
                            ",OUTER_EXT3" +
                            ",OUTER_CONTENT1" +
                            ",OUTER_CONTENT2" +
                            ",OUTER_CONTENT3" +
                            ",OUTER_CONTENT4" +
                            ",OUTER_CONTENT5" +
                            ",OUTER_CONTENT6" +
                            ",OUTER_CONTENT7" +
                            ",OUTER_CONTENT8" +
                            ",OUTER_CONTENT9" +
                            ",OUTER_CONTENT10" +
                            ") " +
                            " VALUES " +
                            " (:ID, :ISEND" +
                            ",:BINDID" +
                            ",:BPM_BOID" +
                            ",:BPM_EXT1" +
                            ",:BPM_EXT2" +
                            ",:BPM_TABLE" +
                            ",:OUTER_TABLE" +
                            ",:OUTER_PK" +
                            ",:OUTER_EXT1" +
                            ",:OUTER_EXT2" +
                            ",:OUTER_EXT3" +
                            ",:OUTER_CONTENT1" +
                            ",:OUTER_CONTENT2" +
                            ",:OUTER_CONTENT3" +
                            ",:OUTER_CONTENT4" +
                            ",:OUTER_CONTENT5" +
                            ",:OUTER_CONTENT6" +
                            ",:OUTER_CONTENT7" +
                            ",:OUTER_CONTENT8" +
                            ",:OUTER_CONTENT9" +
                            ",:OUTER_CONTENT10" +
                            ") "

                    , params
            );
        } else {
            params.put("ID", map.getString("ID"));
            DBSql.update(connection,
                    " UPDATE  BO_EU_HISTRANS_LOG SET  " +
                            " BINDID = :BINDID" +
                            ",BPM_BOID = :BPM_BOID" +
                            ",BPM_EXT1 = :BPM_EXT1" +
                            ",BPM_EXT2 = :BPM_EXT2" +
                            ",BPM_TABLE = :BPM_TABLE" +
                            ",OUTER_TABLE = :OUTER_TABLE" +
                            ",OUTER_PK = :OUTER_PK" +
                            ",OUTER_EXT1 = :OUTER_EXT1" +
                            ",OUTER_EXT2 = :OUTER_EXT2" +
                            ",OUTER_EXT3 = :OUTER_EXT3" +
                            ",OUTER_CONTENT1 = :OUTER_CONTENT1" +
                            ",OUTER_CONTENT2 = :OUTER_CONTENT2" +
                            ",OUTER_CONTENT3 = :OUTER_CONTENT3" +
                            ",OUTER_CONTENT4 = :OUTER_CONTENT4" +
                            ",OUTER_CONTENT5 = :OUTER_CONTENT5" +
                            ",OUTER_CONTENT6 = :OUTER_CONTENT6" +
                            ",OUTER_CONTENT7 = :OUTER_CONTENT7" +
                            ",OUTER_CONTENT8 = :OUTER_CONTENT8" +
                            ",OUTER_CONTENT9 = :OUTER_CONTENT9" +
                            ",OUTER_CONTENT10 = :OUTER_CONTENT10 WHERE ID = :ID"

                    , params
            );

        }
    }

    public void persistFile(Connection connection, HistoryTransContext historyTransContext) throws IOException {
        String drpType=historyTransContext.getType();
        List<FileTransData> fileTransDatas = historyTransContext.getFileTransDatas();
        for(FileTransData fileTransData: fileTransDatas){
           /* FileHelper.uploadToBpm(
                    fileTransData.getBoId(),
                    fileTransData.getBoName(),
                    fileTransData.getBoId(),
                    fileTransData.getFieldName(),
                    fileTransData.getProcessInstId()

            );*/
            if(StringUtils.equals(DrpConst.ZZ_DRP_1_WORKFLOW_CCID,drpType)){

            }else {
                //drp 2.0附件上传方法
                FileUtil.uploadFileByJsonArray(fileTransData);
            }
        }
    }
}
